﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CalcHostView;
using System.AddIn;
using System.AddIn.Hosting;
using System.IO;
using System.Collections.ObjectModel;

namespace CalcHost
{
    class Program
    {
        static void Main(string[] args)
        {

            string addInRoot = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "CalculatorV1\\PipeLine");
            //update the cache files of pipeline segments and add-ins 
            string[] warnings = AddInStore.Update(addInRoot);
            Console.WriteLine("The warnings are:");
            foreach (string warn in warnings)
            {
                Console.WriteLine(warn);
            }
            Console.WriteLine();

            Collection<AddInToken> tokens = AddInStore.FindAddIns(typeof(ICalculator),addInRoot);
            //Ask the user which AddIn he would like to use;
            AddInToken calcToken = ChooseCalcToken(tokens);

            ICalculator calculator = calcToken.Activate<ICalculator>(AddInSecurityLevel.Intranet);


            RunCalculator(calculator);
        }


        private static AddInToken ChooseCalcToken(Collection<AddInToken> addInTokens)
        {
            if (addInTokens.Count == 0)
            {
                Console.WriteLine ("There is no AddIn Token !");
                return null;
            }

            AddInToken token = null;
            Console.WriteLine("There are {0} tokens!",addInTokens .Count );
            Console.WriteLine("The avaible tokens are:");
            int tokNumber = 1;
            foreach (AddInToken tok in addInTokens)
            {
                Console.WriteLine(String.Format("\t[{0}]: {1} - {2}\n\t{3}\n\t\t {4}\n\t\t {5} - {6}",
                    tokNumber.ToString(),
                    tok.Name,
                    tok.AddInFullName,
                    tok.AssemblyName,
                    tok.Description,
                    tok.Version,
                    tok.Publisher));
                tokNumber++;
            }

            string chooseLine = string.Empty;
            Console.WriteLine("Which token do you like to choose?");
            chooseLine = Console.ReadLine();
            int selection = 0;
            if (Int32.TryParse(chooseLine, out selection))
            {
                if (selection > 0 && selection <= addInTokens.Count)
                { 
                    token = addInTokens[selection - 1];
                    return token;
                }
            }

            Console.WriteLine("Choose {0} is invalid, please choose again!",chooseLine );
            return ChooseCalcToken (addInTokens );
        }

        private static void RunCalculator(ICalculator calc)
        {
            //double d = calc.Mitiply(2, 2);

            if (calc == null)
            {
                //No calculators were found; read a line and exit.
                Console.ReadLine();
            }
            Console.WriteLine("Available operations: +, -, *, /");
            Console.WriteLine("Request a calculation , such as: 2 + 2");
            Console.WriteLine("Type \"exit\" to exit");
            String line = Console.ReadLine();
            while (!line.Equals("exit"))
            {
                // The Parser class parses the user's input.
                try
                {
                    Parser c = new Parser(line);
                    switch (c.Action)
                    {
                        case "+":
                            Console.WriteLine(calc.Add(c.A, c.B));
                            break;
                        case "-":
                            Console.WriteLine(calc.Substract (c.A, c.B));
                            break;
                        case "*":
                            Console.WriteLine(calc.Mitiply (c.A, c.B));
                            break;
                        case "/":
                            Console.WriteLine(calc.Divide(c.A, c.B));
                            break;
                        default:
                            Console.WriteLine("{0} is an invalid command. Valid commands are +,-,*,/", c.Action);
                            break;
                    }
                }
                catch
                {
                    Console.WriteLine("Invalid command: {0}. Commands must be formated: [number] [operation] [number]", line);
                }

                line = Console.ReadLine();
            }

        }
    }

    internal class Parser
    {
        double a;
        double b;
        string action;

        internal Parser(string line)
        {
            string[] parts = line.Split(' ');
            a = double.Parse(parts[0]);
            action = parts[1];
            b = double.Parse(parts[2]);
        }

        public double A
        {
            get { return a; }
        }

        public double B
        {
            get { return b; }
        }

        public string Action
        {
            get { return action; }
        }
    }

}
